class Fsm:
    
    def __init__(self):
        #states[i] = stateName
        self.states = set()
        #transitions[(input_symbol, state) -> nextState]
        self.transitions = {}
        

    
    def readFromFile(self, filename):
        f = open(filename, "r")
        for line in f:
            line = line.strip()
            if line and line[0] == 'V':
                parameters = line.split(':')
                symbol = parameters[3]
                state = parameters[1]
                nextState = parameters[2]
                
                if not self.transitions.has_key((symbol, state)):
                    self.transitions[(symbol, state)] = set()
                    
                self.transitions[(symbol, state)].add(nextState)
                
                if state not in self.states:
                    self.states.add(state)
                
                if nextState not in self.states:
                    self.states.add(nextState)
        f.close()
    
    def readFromDot(self, filename):
        f = open(filename, "r")
        lines = f.readlines()
        f.close()
        for i in range(1, len(lines)-1):
            
            line = lines[i]
            if len(line) > 17:
                line = line.strip()
                
                line = line.split('->')
                state = line[0].strip() 
    
                line = line[1].split('[label="')
                nextState = line[0].strip()
                
                line = line[1].split('"];')
                symbol = line[0].strip()

                if not self.transitions.has_key((symbol, state)):
                    self.transitions[(symbol, state)] = set()
                    
                self.transitions[(symbol, state)].add(nextState)
                
                if state not in self.states:
                    self.states.add(state)
                
                if nextState not in self.states:
                    self.states.add(nextState)

    def nextPossibleStates(self, inputStates, symbol):

        nextPossibleStates = set()
        if inputStates:
            for inputState in inputStates:
                possibleStates = self.transitions.get((symbol, inputState))
                if possibleStates:
                    for possibleState in possibleStates:
                        if possibleState not in nextPossibleStates:
                            nextPossibleStates.add(possibleState)            
        return nextPossibleStates
    
class CountingInvocationsFsm(Fsm, object):
    
    def __init__(self):
        super(CountingInvocationsFsm, self).__init__()
        self.numberOfNextStatesInvocation = 0
        
    def nextPossibleStates(self, inputStates, symbol):
        self.numberOfNextStatesInvocation += 1
        return super(CountingInvocationsFsm, self).nextPossibleStates(inputStates, symbol)
